#include <stdio.h>
#include <malloc.h>
#include <stdbool.h>

#define MAX_SIZE 100

typedef char ElemType;
typedef struct
{
    ElemType data[MAX_SIZE];
    int queue_front;// 队首指针
    int queue_rear; //队尾指针
}SeqQueue; // 声明环形队列类型


/*----------------------初始化队列------------------------*/
static void init_queue(SeqQueue *&q) // 指针的引用
{
    // 初始化队列头
    q = (SeqQueue *)malloc(sizeof(SeqQueue)); // 动态分配存储空间
    q->queue_front = q->queue_rear = 0;
}

/*----------------------销毁队列q------------------------*/
static void destroy_queue(SeqQueue *&q)
{
    free(q);
}

/*----------------------判断队列q是否空------------------------*/
static bool queue_empty(SeqQueue *q)
{
    return (q->queue_front == q->queue_rear);
}

/*----------------------入队------------------------*/
static bool enter_queue(SeqQueue *&q, ElemType e)
{
    // 队满,上溢出,返回假
    if((q->queue_rear + 1) % MAX_SIZE == q->queue_front)
        return false;

    q->queue_rear = (q->queue_rear + 1) % MAX_SIZE; // 计算队尾指针
    q->data[q->queue_rear] = e; // 将元素e入队

    return true;
}

/*----------------------出队------------------------*/
static bool de_queue(SeqQueue *&q, ElemType &e)
{
    // 队空,下溢出,返回假
    if(q->queue_front == q->queue_rear)
        return false;

    q->queue_front = (q->queue_front + 1) % MAX_SIZE; // 计算队首指针
    e = q->data[q->queue_front]; // 提取队列中的元素

    return true;
}

int main(int argc, char *argv[])
{
    ElemType e;
    SeqQueue *q;

    printf("环形队列基本运算如下:\n");
    printf("   (1)初始化队列q\n");
    init_queue(q);
    printf("   (2)依次进队元素a、b、c\n");
    if(!enter_queue(q, 'a'))
        printf("\t提示:队满,不能入队\n");
    if(!enter_queue(q, 'b'))
        printf("\t提示:队满,不能入队\n");
    if(!enter_queue(q, 'c'))
        printf("\t提示:队满,不能入队\n");
    printf("   (3)队列为%s\n", (queue_empty(q) ? "空" : "非空"));
    if(!de_queue(q, e))
        printf("队空,不能出队\n");
    else
        printf("   (4)出队一个元素%c\n", e);

    printf("   (5)依次进队元素d、e、f\n");
    if(!enter_queue(q, 'd'))
        printf("\t提示:队满,不能入队\n");
    if(!enter_queue(q, 'e'))
        printf("\t提示:队满,不能入队\n");
    if(!enter_queue(q, 'f'))
        printf("\t提示:队满,不能入队\n");

    printf("   (6)出队列序列: ");
    while(!queue_empty(q))
    {
        de_queue(q, e);
        printf("%c ", e);
    }
    printf("\n");
    printf("   (7)释放队列\n");
    destroy_queue(q);

    return 0;
}
